#region Usings

using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Karma.Framework.Core.Domain;
using Karma.Framework.Core.Repository.Configuration;
using Karma.Framework.Core.Serialization.Json.Converters;
using Karma.Framework.Core.Utils;

#endregion

namespace Karma.Framework.Core.Serialization
{
    public class Configuration
    {
        protected static JsonConverter[] _entityConverters;

        protected static JsonConverter[] _enumConverters;

        public static JsonConverter[] AllConverters
        {
            get
            {
                return
                    (from e in _entityConverters select e).Concat(
                        from o in _enumConverters select o).ToArray();
            }
        }

        public static JsonConverter[] EnumConverters
        {
            get
            {
                if (_enumConverters == null ||
                    _enumConverters.Length == 0)
                {
                    var section = (ActiveRecordConfigurationSectionHandler)
                                  ConfigurationManager.GetSection(
                                      ActiveRecordConfigurationSectionHandler.SECTION_NAME);

                    var enums = new List<JsonConverter>();
                    foreach (AssemblyElement assembly in section.Assemblies)
                    {
                        var asm = Assembly.Load(assembly.FullName);
                        var converters = from t in asm.GetTypes().AsEnumerable()
                                         where t.IsEnum
                                         select
                                             (JsonConverter) ReflectionUtils.CreateGenericInstance(
                                                                 typeof (EnumConverter<>), t);

                        enums.AddRange(converters);
                    }

                    _enumConverters = enums.ToArray();
                }
                return _enumConverters;
            }
        }

        public static JsonConverter[] EntityConverters
        {
            get
            {
                if (_entityConverters == null ||
                    _entityConverters.Length == 0)
                {
                    var section = (ActiveRecordConfigurationSectionHandler)
                                  ConfigurationManager.GetSection(
                                      ActiveRecordConfigurationSectionHandler.SECTION_NAME);

                    var enums = new List<JsonConverter>();
                    foreach (AssemblyElement assembly in section.Assemblies)
                    {
                        var asm = Assembly.Load(assembly.FullName);
                        var converters = from t in asm.GetTypes().AsEnumerable()
                                         where typeof (DomainObject).IsAssignableFrom(t)
                                               && !t.IsInterface
                                               && !t.IsAbstract
                                         select
                                             (JsonConverter) ReflectionUtils.CreateGenericInstance(
                                                                 typeof (DomainObjectConverter<>),
                                                                 t);

                        enums.AddRange(converters);
                    }

                    _entityConverters = enums.ToArray();
                }
                return _entityConverters;
            }
        }
    }
}